package com.creative.utils;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.creative.config.AppConfig;
import com.creative.xcx.domain.dto.MpUserDto;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.creative.constant.Constants.CACHE_ACCESS_TOKEN_KEY;

/**
 * 素材检查
 * 创建人: ling
 * 创建时间: 2025/05/13
 */
@Component("materialCheckUtils")
public class MaterialCheckUtils {
    public static final Log logger = LogFactory.get();
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private AppConfig appConfig;

    /**
     * 检测图片内容安全
     *
     * @param imgurl 地址
     * @return boolean
     * @author ling
     * @date 2025/05/13
     */
    public boolean checkMaterialImage(String imgurl) {

        if (imgurl == null) {
            return false;
        }
        //       1.获取接口调用凭据
        //        查看redis缓存中是否存在小程序的access_token
        String accessToken;
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(CACHE_ACCESS_TOKEN_KEY))) {
            //            存在，则使用缓存的access_token
            accessToken = stringRedisTemplate.opsForValue().get(CACHE_ACCESS_TOKEN_KEY);
        } else {
            // 获取 access_token 并缓存
            StrBuilder tokenUrl = StrBuilder.create()
                    .append("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential")
                    .append("&appid=").append(appConfig.getXcxAppId())
                    .append("&secret=").append(appConfig.getXcxAppSecret());
            String tokenResult = HttpUtil.get(tokenUrl.toString());
            // 解析 JSON 获取 accessToken，并缓存到 Redis
            accessToken = parseAccessTokenFromJson(tokenResult);
            if (accessToken == null) {
                return false;
            }
//            设置缓存
            stringRedisTemplate.opsForValue().set(CACHE_ACCESS_TOKEN_KEY, accessToken, 7200, TimeUnit.SECONDS);
        }
//        获取用户openId
        SaSession session = StpUtil.getSession();
        String userId = (String) StpUtil.getLoginId();
        MpUserDto mpSession = (MpUserDto) session.get("MpSession" + userId);
        logger.info("用户openId为：" + mpSession.getOpenId());

        // 发起内容安全检测请求
        StrBuilder url = StrBuilder.create()
                .append("https://api.weixin.qq.com/wxa/media_check_async?access_token=")
                .append(accessToken);

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("openid", mpSession.getOpenId());
        paramMap.put("scene", 1);
        paramMap.put("version", 2);
        paramMap.put("media_type", 2);
        paramMap.put("media_url", imgurl);

        String response = HttpUtil.post(String.valueOf(url), JSONUtil.toJsonStr(paramMap));
        // 解析响应，判断是否合法
        return isContentSafe(response);
    }


    /**
     * 从json解析访问令牌
     *
     * @param jsonStr json str
     * @return {@link String }
     * @author ling
     * @date 2025/05/12
     */
    public String parseAccessTokenFromJson(String jsonStr) {
        if (StrUtil.isBlank(jsonStr)) {
            return null;
        }

        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);

        // 提取 access_token
        String accessToken = jsonObject.getStr("access_token");

        // 提取 expires_in（例如：7200）
        int expiresIn = jsonObject.getInt("expires_in", 7200); // 默认值 7200

        // 可以根据业务需要记录日志或处理异常情况
        if (StrUtil.isBlank(accessToken)) {
            // 记录错误信息
            logger.error("获取 access_token 失败，响应内容: {}", jsonStr);
            return null;
        }

        return accessToken;
    }

    public boolean isContentSafe(String response) {
        JSONObject jsonObject = JSONUtil.parseObj(response);
        int errcode = jsonObject.getInt("errcode");
        if (errcode == 0) {
            // 内容安全检测通过
            return true;
        } else {
            // 内容安全检测失败
            return false;
        }
    }
}
